package com.smartstate.EnvironmentMonitor.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.smartstate.EnvironmentMonitor.dto.PageDTO;
import com.smartstate.EnvironmentMonitor.dto.ReportDTO;
import com.smartstate.EnvironmentMonitor.entity.Report;
import com.smartstate.EnvironmentMonitor.mapper.DataMapper;
import com.smartstate.EnvironmentMonitor.mapper.HistoryMapper;
import com.smartstate.EnvironmentMonitor.mapper.ObjMoudelMapper;
import com.smartstate.EnvironmentMonitor.service.ReportService;
import com.smartstate.EnvironmentMonitor.vo.ResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@RestController
@Slf4j
@Api(tags = {"报表管理器"})
@RequestMapping("/report")
public class ReportController {

    @Resource
    private ReportService reportService;

    @Resource
    private DataMapper dataMapper;

    @Resource
    private ObjMoudelMapper objMoudelMapper;

//    /**
//     * 日报查询默认单位分，月表查询默认单位时
//     * @param
//     * @return
//     */
//    @PostMapping("/queryByCondition")
//    @ApiOperation(value = "日报或月报查询或自定义查询")
//    public ResultVO<List<Report>> queryByCondition(@RequestBody PageDTO pageDTO) {
//        return ResultVO.ok(reportService.queryByCondition(pageDTO));
//    }


//    /**
//     * 开始时间与结束时间为一天之内，单位才能设置为秒，超过七天单位为时，一般默认分
//     * @param reportDTO
//     * @return
//     */
//    @PostMapping("/queryByReportDTO")
//    @ApiOperation(value = "自定义查询")
//    public ResultVO<List<Report>> queryByReportDTO(@RequestBody ReportDTO reportDTO) throws Exception {
//        return ResultVO.ok(reportService.queryByReportDTO(reportDTO));
//    }

    /**
     * 分页查询 + 日月报查询 + 自定义查询
     * @param pageDTO
     * @return
     */
    @PostMapping ("/getReportBySpec")
    @ApiOperation(value = "单表分页查询")
    public ResultVO<IPage<Report>> getReportBySpec(@RequestBody PageDTO<ReportDTO> pageDTO) {
        IPage<Report> reportPage = reportService.queryAllPageByPageDTO(pageDTO);
        return ResultVO.ok(reportPage);
    }

    @PostMapping("/exportExcel")
    @ApiOperation(value = "导出报表信息excel")
    public ResultVO exportExcel(HttpServletResponse response, @RequestBody PageDTO<ReportDTO> pageDTO) throws IOException {
        log.info("开始导出excel");
        List<Map<String, String>> mapList = reportService.exportExcel(pageDTO);
        setExcelRespProp(response, "报表信息列表");
//        获取objid对于名称
        String totalName = dataMapper.queryObjIdName(pageDTO.getDto().getId());
        if (CollectionUtils.isEmpty(mapList) || mapList.size() <= 0){
            return ResultVO.fail("报表信息为空");
        }
//        获取deviceId集合
        List<String> deviceIdList = new ArrayList<>();
        for (String key : mapList.get(0).keySet()) {
            if(key != "time"){
                String deviceId = key.substring(0, key.indexOf("."));
                if (!deviceIdList.contains(deviceId)){
                    deviceIdList.add(deviceId);
                }
            }
        }
//        获取deviceId对应的设备名称
        List<String> deviceIdNames = new ArrayList<>();
        for (String deviceId : deviceIdList) {
            deviceIdNames.add(dataMapper.queryDeviceName(deviceId));
        }
        EasyExcel.write(response.getOutputStream())
                .head(head(totalName, deviceIdNames))
                .excelType(ExcelTypeEnum.XLSX)
                .sheet("报表信息列表")
                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(25))
                .doWrite(getData(mapList, deviceIdList));
        log.info("导出excel成功");
        return null;
    }

    /**
     * 设置excel下载响应头属性
     */
    private void setExcelRespProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(rawFileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    }

    /**
     * 表目录
     * @return
     */
    private List<List<String>> head(String totalName, List<String> deviceIdList) {
        List<List<String>> list = new ArrayList<List<String>>();
        List<String> productHead = new ArrayList<>();
//        productHead.add("时间");
        productHead.add("温度/℃");
        productHead.add("湿度/％");
        productHead.add("尘埃粒子5.0 / 万颗/m³");
        productHead.add("尘埃粒子0.5 / 万颗/m³");
        productHead.add("静压/Pa");
        productHead.add("露点/℃");
        List<String> arrayList = new ArrayList<>();
        arrayList.add("时间");
        list.add(arrayList);
        for (String name : deviceIdList) {
            for (String attribute : productHead) {
                String objId = dataMapper.queryObjIdByDeviceId(name);
                List<String> objects = new ArrayList<>();
                objects = queryTree(objects, objId);
                Collections.reverse(objects);
                List<String> totalList = new ArrayList<>();
                if (!objects.contains(totalName)){
                    totalList.add(totalName);
                }
                for (String object : objects) {
                    totalList.add(object);
                }
                totalList.add(name);
                totalList.add(attribute);
                list.add(totalList);
            }
        }
        return list;
    }

    /**
     * 表数据
     * @return
     */
    public List<List<String>> getData(List<Map<String, String>> excelData, List<String> deviceIdList){
        List<List<String>> total=new ArrayList<>();
        for (Map<String, String> excelDatum : excelData) {
            List<String> list = new ArrayList<>();
            list.add(excelDatum.get("time"));
            for (String deviceId : deviceIdList) {
                list.add(excelDatum.get(deviceId + "." + "temperature"));
                list.add(excelDatum.get(deviceId + "." + "humidity"));
                list.add(excelDatum.get(deviceId + "." + "longParticle"));
                list.add(excelDatum.get(deviceId + "." + "littleParticle"));
                list.add(excelDatum.get(deviceId + "." + "staticPressure"));
                list.add(excelDatum.get(deviceId + "." + "dewPoint"));
            }
            total.add(list);
        }
        return total;
    }

    /**
     * 递归查询objId之下的树
     * @param list
     * @param objId
     * @return
     */
    public List<String> queryTree(List<String> list, String objId){
        Map map = objMoudelMapper.queryName(objId);
        if (map == null || map.size() == 0) {
            return list;
        }
        list.add((String) map.get("name"));
        list = queryTree(list, (String) map.get("parentId"));
        return list;
    }

}
